﻿using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using Framework.Exceptions.RepositoryExceptions;
using HelperTools;
using Interfaces.Filters;
using Interfaces.Models;
using Interfaces.Providers;
using Interfaces.Repositories;
using Interfaces.RepositoryModels.InternalModels.NewsInformationModels;

namespace SQLRepositories.NewsRepositories
{
    public class FeedRepository : EntityBaseRepository<FeedModel>, IFeedRepository, INewsDataProvider<IFeed, IFilter>
    {
        public FeedRepository(IDBEconomicInformationServiceContext context) : base(context)
        {}

        public void Create(FeedModel item)
        {
            Context.Feeds.Add(item);
            Context.SaveChanges();
        }

        public FeedModel GetById(Guid id)
        {
            return Context.Feeds.FirstOrDefault(x => x.Id.Equals(id));
        }

        public void Delete(Guid id)
        {
            var feed = Context.Feeds.FirstOrDefault(x => x.Id.Equals(id));
            if (feed == null)
                throw new EntityNotFoundException("Feed");
            Context.Feeds.Remove(feed);
            Context.SaveChanges();
        }

        public void Delete(FeedModel item)
        {
            Context.Feeds.Remove(item);
            Context.SaveChanges();
        }

        public IEnumerable<FeedModel> GetAll()
        {
            return Context.Feeds;
        }

        public IFeed GetData(string url, IFilter itemsFilter)
        {
            var resultFeed = (from feed in Context.Feeds where feed.BaseUri.Equals(url) 
                              orderby feed.CreatedDate select feed).FirstOrDefault();
            if (resultFeed != null)
            {
               var resultNews = itemsFilter.Filtrate(resultFeed.With(x => x.Items)) as IEnumerable<NewsDataItemModel>;

               return Map(resultFeed, resultNews);
            }
            return null;
        }

        private static IFeed Map(FeedModel resultFeed, IEnumerable<NewsDataItemModel> itemsCollection)
        {
            Mapper.Reset();
            Mapper.CreateMap<PersonModel, IPerson>();
            Mapper.CreateMap<NewsDataItemModel, INewsDataItem>()
                .ForMember(x => x.SourceFeed, opt => opt.Ignore());

            Mapper.CreateMap<FeedModel, IFeed>()
                   .ForMember(dst => dst.Items, opt => opt.ResolveUsing(x => Mapper.Map<IEnumerable<NewsDataItemModel>, IEnumerable<INewsDataItem>>(itemsCollection)))
                   .ForMember(dst => dst.Persons, opt => opt.ResolveUsing(x => Mapper.Map<IEnumerable<PersonModel>, IEnumerable<IPerson>>(x.Persons)));

            var result = Mapper.Map<FeedModel, IFeed>(resultFeed);

            foreach (var newsDataItemModel in result.Items)
                newsDataItemModel.SourceFeed = result;

            return result;
        }
    }
}
